﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Web.Http;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using CN2P.Recommendations.WebApi;
using CN2P.Recommendations.WebApi.Controllers;
using CN2P.Recommendations.Repository.Interfaces.Fakes;
using CN2P.Recommendations.DomainModel;

namespace CN2P.Recommendations.WebApi.Tests.Controllers
{
    [TestClass]
    public class RecommendationControllerTest
    {
        [TestMethod]
        public void GetById()
        {
            // Arrange

            var fakeRepository = new StubIProductRecommendationRepository();
            fakeRepository.GetRecommendationsStringArray = (prodId) =>
                {
                    Assert.AreEqual(1, prodId.Length, "Only one product id should be received");
                    Assert.AreEqual("1", prodId[0], "Product id not expected value");

                    var products = new List<ProductReference>
                    {
                        new ProductReference{ ProductId = "11", AverageRating = 3.5f },
                        new ProductReference{ ProductId = "12", AverageRating = 4.0f }
                    };

                    return products;
                };
            
            var controller = new RecommendationController(fakeRepository);

            // Act
            var result = controller.Get(new string[] { "1" });

            // Assert
            Assert.IsNotNull(result, "Didn't receive a result at all");
            Assert.AreEqual(2, result.Count(), "Didn't receive expected ammount of recommendations");
            Assert.AreEqual("11", result.ElementAt(0), "First recommendation id was incorrect");
            Assert.AreEqual("12", result.ElementAt(1), "Second recommenation id was incorrect");
        }

        //[TestMethod]
        //public void PostTraversal()
        //{
        //    // Arrange
        //    var fakeRepository = new StubIProductRecommendationRepository();
        //    var repositoryCalled = false;
        //    fakeRepository.AddRecommendationTraversalStringString = (from, to) =>
        //        {
        //            Assert.AreEqual("1", from, "Didn't expect traversal from...");
        //            Assert.AreEqual("2", to, "Didn't expect traversal to...");

        //            repositoryCalled = true;

        //            return new ProductRecommendation { SourceProductId = from, TargetProductId = to, Weight = 5 };
        //        };
            
        //    RecommendationController controller = new RecommendationController(fakeRepository);

        //    // Act
        //    controller.PostTraversal(
        //        from: "1",
        //        to: "2");

        //    // Assert
        //    // Controller doesn't return any data, hence we only make sure the repository was invoked.
        //    Assert.IsTrue(repositoryCalled, "Repository method AddRecommendationTraversal() wasn't called");
        //}

        //[TestMethod]
        //public void PostRating()
        //{
        //    // Arrange
        //    var fakeRepository = new StubIProductRecommendationRepository();
        //    var repositoryCalled = false;
        //    fakeRepository.SubmitProductRatingStringSingle = (prodId, avgRating) =>
        //        {
        //            Assert.AreEqual("1", prodId, "Unexpected product id");
        //            Assert.AreEqual(3.5f, avgRating, "Unexpected average rating");

        //            repositoryCalled = true;

        //            return new ProductReference { ProductId = prodId, AverageRating = avgRating };
        //        };

        //    RecommendationController controller = new RecommendationController(fakeRepository);

        //    // Act
        //    controller.PostRating(
        //        prodId: "1",
        //        avgRating: 3.5f);

        //    // Assert
        //    // Controller doesn't return any data, hence we only make sure the repository was invoked.
        //    Assert.IsTrue(repositoryCalled, "Repository method SubmitProductRating() wasn't called");
        //}
    }
}
